var createError = require('http-errors');
var fs = require('fs');
var express = require('express');
var path = require('path');
var cookie = require('cookie-parser');
var session = require('express-session');
var logger = require('morgan');
var helmet = require('helmet');
var compression = require('compression');

var app = express();
//尽量在其他中间件前使用compression
app.use(compression());
var envConfig = require('./env/env.config');
var utils = require('./source/utils');

//通过pm2命令行带上环境参数 pm2 start config.js --env dev/uat/prod
const env = process.env.NODE_ENV || 'local';

//source/xxx.js是源文件，根据配置文件生成新的xxx.js放到javascripts/common/
// const copyFiles = ['common', 'bdhI18n'];
// copyFiles.map(name => {
//   let commonFileData = fs.readFileSync('./source/' + name + '.js', 'utf-8');
//   let newFile = utils.formatFile(commonFileData, envConfig[env]);
//   fs.writeFile('./public/javascripts/common/' + name + '.js', newFile, function (res) { });
// });

//非本地开发环境
// if (env != "local") {
//   //静态资源增加随机数刷新浏览器缓存
//   require('./source/template');
// }

// view engine setup
app.set('views', path.join(__dirname, 'public'));
app.engine('html', require('ejs').renderFile);
app.set('view options', {
  // debug: process.env.NODE_ENV !== 'production'
});
app.set('view engine', 'html');

//设置日志
var logDirectory = path.join(__dirname, './logs');
fs.existsSync(logDirectory) || fs.mkdirSync(logDirectory);

//临时文件存放目录，不存在则创建
// var fileTemp = path.join(__dirname, './assets');
// var fileTempSub = path.join(__dirname, './assets/files_temporary');
// fs.existsSync(fileTemp) || fs.mkdirSync(fileTemp);
// fs.existsSync(fileTempSub) || fs.mkdirSync(fileTempSub);

//  设置public
var publicDirectory = path.join(__dirname, './public');
fs.existsSync(publicDirectory) || fs.mkdirSync(publicDirectory);

var attachFileList = ['tmp', 'failFile'];
attachFileList.map(v => {
  let dirName = path.join(__dirname, `./public/${v}`);
  fs.existsSync(dirName) || fs.mkdirSync(dirName);
});
var rfs = require('rotating-file-stream');
var accessLogStream = rfs.createStream('access.log', {
  interval: '1d',
  size: "1G",
  path: logDirectory
});
var errorLogStream = rfs.createStream('error.log', {
  interval: '1d',
  size: "1G",
  path: logDirectory
});
logger.token('realIp', function (req, res) { return req.headers['x-real-ip'] || req.connection.remoteAddress });
logger.token('body', function (req, res) { return JSON.stringify(req.body) });
logger.token('resBody', function (req, res) { return res._resBody && JSON.stringify(res._resBody); });
var logContent = '[:date] ":method :url" :status :body :response-time ms :resBody ":realIp"';

app.use(logger(logContent, {
  stream: accessLogStream,
  skip: function (req, res) {
    return req.baseUrl && req.baseUrl.indexOf('helloBdh') > -1;
  }
}));
app.use(logger(logContent, {
  stream: errorLogStream,
  skip: function (req, res) { return res.statusCode < 400; }
}));

app.use(cookie());
//扩大json提交内容大小1mb到20mb，解决403：request too large的问题
app.use(express.json({ limit: "20mb" }));
app.use(express.urlencoded({ extended: false, limit: "20mb" }));

app.set('trust proxy', 1) // trust first proxy

// var expiryDate = new Date( Date.now() + 60 * 60 * 1000 ); // 1 hour
app.use(session({
  name: 'NODE_TAX_PORTAL',
  secret: '13527418320',
  // cookie: { maxAge: 3600000 * 24 * 30, httpOnly: true, secure: true },
  resave: false,
  saveUninitialized: false,
  // store: new MemoryStore(), //or other session store
  // store: new RedisStore({
  //   port: '7001',
  //   host: '10.100.0.119'
  // })
}));

//全局配置国际化
let i18n = require("i18n");
i18n.configure({
  register: global,
  locales: envConfig[env].language.locales,
  directory: __dirname + '/lang',
  defaultLocale: envConfig[env].language.default,
  cookie: 'lang',
  autoReload: false,
  objectNotation: true
});
// var hbs = require("handlebars");
// hbs.registerHelper('__', function () {
//   return i18n.__.apply(this, arguments);
// });
// 定义setLocale中间件
function setLocale(req, res, next) {
  let ingore = [".js", ".css", "images/"];
  let hasItem = ingore.filter((i) => {
    return req.path.indexOf(i) > 0;
  });
  if (hasItem.length == 0) {
    let defaultLang = envConfig[env].language.default;
    let lang = defaultLang;
    //请求中不带lang参数则设置默认语言
    if (req.cookies.lang) {
      //香港环境客户端传入cn时，需转换为hk
      lang = (defaultLang == 'hk' && req.cookies.lang == 'cn') ? "hk" : req.cookies.lang;
    }
    else {
      //客户端国际化默认语言设置，香港环境展示cn
      res.cookie('lang', defaultLang == 'hk' ? 'cn' : defaultLang, {
        maxAge: 3600000 * 24 * 30,
        secure: "local" != env ? true : false
      });
    }
    i18n.init(req, res);
    req.setLocale(lang);
  }
  next();
};
// 添加setLocale中间件，注意必须在session之后
app.use(setLocale);

//缓存设置10分钟
app.use(express.static(path.join(__dirname, 'public'), { maxAge: 1000 * 60 * 10 }));

app.use(function (req, res, next) {
  if (env === 'local') {
    res.header('Access-Control-Allow-Origin', 'http://localhost:3000')
    res.header('Access-Control-Allow-Credentials', 'true') //允许跨域设置cookie
  }
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, access-control-allow-origin, lang");
  next();
});

//security
// Make sure you run "npm install helmet" to get the Helmet package.
app.use(helmet());
app.use(helmet.frameguard({ action: 'sameorigin' }));

//set router
var indexRouter = require('./routes/index');
app.use('/', indexRouter);

// 如果是options请求，就直接响应
app.use('/bdhapi', (req, res, next) => {
  if (req.method === 'OPTIONS') {
    res.end();
  } else {
    next();
  }
});

var auth = require('./routes/rights/authentication');
//请求鉴权
app.use('/bdhapi', async (req, res, next) => {
  //  以下路由不做权限校验;
  const ignorePath = [ 'getPublicReportInfo', 'validateReportPwd', 'getPublicAnalysePageConfig', 'getPublicComponentData' ];

  //  把参数中的tenantCode放到header
  if( ignorePath.some( v => req.url.indexOf(v) > -1 ) ) {
    req.headers.user = {
      tenantCode: req.body.tenantCode || ''
    };
    return next();
  };

  let tokenUser = await auth.checkRouterAuth(req, res);
  if (tokenUser) {
    req.headers.user = tokenUser;
    next();
  }
  else {
    //跳转登录页面
    auth.toLogin(req, res);
  }
});

//bi文件上传
var biUploadRouter = require('./routes/uploadfilebi')
app.use('/bdhapi/uploadfileBI',biUploadRouter )

var uploadfileRouter = require('./routes/uploadfile')
app.use('/bdhapi/uploadfile', uploadfileRouter)

var bdhapiRouter = require('./routes/apiModules/index');
app.use('/bdhapi', bdhapiRouter);



//slb健康检查请求地址，勿删！！！
app.use('/helloBdh', function (req, res, next) {
  res.end();
});

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  next(createError(404));
});

// error handler
app.use(function (err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  let renderData = { data: err };
  console.log(err);
  res.redirect(envConfig[env].domain);
});


module.exports = app;
